#include "gd32f30x.h"
#include "stdint.h"
#include "stdio.h"
#include "DevicesDelay.h"
#include "DevicesHT1621.h"


void vHT1621Init(void)
{
    /* enable the GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOD);

    /* configure GPIO pin */
    gpio_init(HT1621_CS1_GPIO_Port,     GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, HT1621_CS1_Pin);
    gpio_init(HT1621_CS2_GPIO_Port,     GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, HT1621_CS2_Pin);
    gpio_init(HT1621_WR_GPIO_Port,      GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, HT1621_WR_Pin);
    gpio_init(HT1621_RD_GPIO_Port,      GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, HT1621_RD_Pin);
    gpio_init(HT1621_VLCD_GPIO_Port,    GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, HT1621_VLCD_Pin);
    gpio_init(HT1621_DATA_GPIO_Port,    GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, HT1621_DATA_Pin);


    HT1621_CS1_HIGH();
    HT1621_CS2_HIGH();
    HT1621_WR_HIGH();
    HT1621_RD_HIGH();
    HT1621_DATA_HIGH();
    HT1621_VLCD_HIGH();
}

void vHT1621WriteMode(uint8_t ucMode)
{
    uint8_t ucMask = 0x04;

    /* 写入模式：3bit */
    for(ucMask = 0x04; ucMask; ucMask >>= 1)
    {
        HT1621_WR_LOW();

        if(ucMode & ucMask)
            HT1621_DATA_HIGH();
        else
            HT1621_DATA_LOW();
        HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);

        HT1621_WR_HIGH();
        HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);
    }
}

void vHT1621WriteAddr(uint8_t ucAddr)
{
    uint8_t ucMask = 0x20;

    /* 写入地址：6bit */
    for(ucMask = 0x20; ucMask; ucMask >>= 1)
    {
        HT1621_WR_LOW();

        if(ucAddr & ucMask)
            HT1621_DATA_HIGH();
        else
            HT1621_DATA_LOW();
        HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);

        HT1621_WR_HIGH();
        HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);
    }
}

void vHT1621WriteCommand(uint16_t usCommand)
{
    uint16_t usMask = 0;

    /* 设置模式 */
    vHT1621WriteMode(HT1621_MODE_COMMAND);

    /* 左移1位，最低位无关位 */
    usCommand <<= 1;

    /* 写入命令：9bit */
    for(usMask = 0x0100; usMask; usMask >>= 1)
    {
        HT1621_WR_LOW();

        if(usCommand & usMask)
            HT1621_DATA_HIGH();
        else
            HT1621_DATA_LOW();
        HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);

        HT1621_WR_HIGH();
        HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);
    }
}

void vHT1621WriteByte(uint8_t ucAddr, uint8_t ucByte)
{
    vHT1621WriteDatas(ucAddr, &ucByte, 1);
}

void vHT1621WriteDatas(uint8_t ucAddr, uint8_t *pucDatas, int32_t iLength)
{
    uint8_t ucMask = 0x01;

    /* 设置模式 */
    vHT1621WriteMode(HT1621_MODE_WRITE);

    /* 写入地址 */
    vHT1621WriteAddr(ucAddr);

    /* 写入数据：4bit */
    while((iLength--) > 0)
    {
        for(ucMask = 0x01; ucMask != 0x10; ucMask <<= 1)
        {
            HT1621_WR_LOW();

            if(*pucDatas & ucMask)
                HT1621_DATA_HIGH();
            else
                HT1621_DATA_LOW();
            HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);

            HT1621_WR_HIGH();
            HT1621_DELAY_US(HT1621_DELAY_BIT_TIME);
        }

        ++pucDatas;
    }
}
